package com.ruoyi.framework.aspectj

import com.ruoyi.common.annotation.DataSource
import com.ruoyi.common.utils.MyStringUtils
import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Pointcut
import org.aspectj.lang.reflect.MethodSignature
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.core.annotation.AnnotationUtils
import org.springframework.core.annotation.Order
import org.springframework.stereotype.Component
import java.util.*

/**
 * 多数据源处理
 *
 * @author ruoyi
 */
@Aspect
@Order(1)
@Component
open class DataSourceAspect {
    protected var logger: Logger = LoggerFactory.getLogger(javaClass)

    @Pointcut("@annotation(com.ruoyi.common.annotation.DataSource)|| @within(com.ruoyi.common.annotation.DataSource)"
    )
    fun dsPointCut() {
    }

    @Around("dsPointCut()")
    @Throws(Throwable::class)
    fun around(point: ProceedingJoinPoint): Any {
        val dataSource = getDataSource(point)
        if (MyStringUtils.isNotNull(dataSource)) {
            println("dataSourceType赋值")
            DynamicDataSourceContextHolder.dataSourceType=dataSource!!.value.name
        }
        return try {
            point.proceed()
        } finally {
            // 销毁数据源 在执行方法之后
            DynamicDataSourceContextHolder.clearDataSourceType()
        }
    }

    /**
     * 获取需要切换的数据源
     */
    fun getDataSource(point: ProceedingJoinPoint): DataSource? {
        val signature = point.signature as MethodSignature
        val dataSource = AnnotationUtils.findAnnotation(signature.method, DataSource::class.java)
        return if (Objects.nonNull(dataSource)) {
            dataSource
        } else AnnotationUtils.findAnnotation(signature.declaringType, DataSource::class.java)
    }
}
